#include <iostream>
#include <windows.h>
#include <vector>
#include <time.h>

#define _CRT_SECURE_NO_WARNINGS 
using namespace std;
#define Maxnum 4294967296
static unsigned int max_account=0,min_account=0;
int circles=0;
struct Edge
{
	unsigned int v2,weight;
	Edge(unsigned int vv2=0,unsigned int wweight=0):v2(vv2),weight(wweight){};
};
vector<vector<Edge>> Ak;
vector<vector<unsigned int>> B;
vector<bool> blocked;
vector<unsigned int> stack;
vector<vector<unsigned int>> Loop_heap;
vector<unsigned int>::iterator it;
vector<unsigned int>::iterator it2;
vector<vector<unsigned int>>::iterator it3;
//////////////////////////////////////////////////////////////////////////////
void DrawGraph()
{
	unsigned int V1=0,V2=0,Weight=0;
	char dot;
	freopen("data.txt","r",stdin);
	while(scanf("%d",&V1)!=EOF)
    {       
        scanf("%c",&dot);
        scanf("%d",&V2);
        scanf("%c",&dot);
        scanf("%d",&Weight);
		max_account=max(max_account,V1);
		max_account=max(max_account,V2);
		min_account=min(min_account,V1);
		min_account=min(min_account,V2);
		if(Ak.size()<=V1) {Ak.resize(V1+1);} 
		//Ak.resize(max_account);
        Ak[V1].push_back(Edge(V2,Weight));
		//cout<<V1<<V2<<Weight<<endl;
    }
	B.resize(max_account+1);
	blocked.resize(max_account+1);
	cout<<"ok";
    freopen("CON", "r", stdin);
}
////////////////////////////////////////////////////////////////////////////
unsigned int s;
int flag;

void output(unsigned int s1)
{
	Loop_heap.resize(Loop_heap.size()+1);
	it=stack.begin();
	int heap=Loop_heap.size()-1;
	while(it!=stack.end())
	{
		Loop_heap[heap].push_back(*it);
		//printf("%d,",it);
		//cout<<*it<<" ";
		it++;
	}
	if(Loop_heap[heap].size()<8 && Loop_heap[heap].size()>2) circles++; 
	//cout<<endl;
	//freopen("CON", "r", stdin);
}

void UNBLOCK(int u)
{
	blocked[u]=false;
	while(!B[u].empty())
	{
		it2=B[u].begin();
		int w=*it2;
		B[u].erase(it2);
		if(blocked[w]) UNBLOCK(w);
		
	}
}

bool CIRCUIT(unsigned int v)
{
	bool f=false;
	stack.push_back(v);
	blocked[v]=true;
	for(Edge w:Ak[v])
	{
		if(w.v2==s)
		{
			output(s);
			f=true;
		}
		else if(w.v2>s && blocked[w.v2]==false)
		{
			if(CIRCUIT(w.v2)) f=true;
		}
	}
	if(f)
	{
		UNBLOCK(v);
	}
	else
	{
		for(Edge w:Ak[v])
		{
		 flag=0;
			for(it2=B[w.v2].begin();it2!=B[w.v2].end();it2++)
			{
				if(*it2==v){flag++;}
			}
			if(!flag) B[w.v2].push_back(v);
		}
	}
	stack.pop_back();
	return f;
}


void Johson_Search()
{
    s=min_account;
	stack.clear();
	while(s<=max_account)
	{
		if(Ak[s].empty()) ;
		else
		{
			for(int m=s;m<=max_account;m++)
			{
				B[m].clear();
				blocked[m]=false;
			}
			CIRCUIT(s);
		}
		s++;
	}
}

void RESULT()
{
	int b=3;
	//printf("%d",circles);
	cout<<circles<<endl;
	while(b<=7)
	{
		for(it3=Loop_heap.begin();it3!=Loop_heap.end();it3++)
		{
			if(it3->size()==b)
			{
			for(it2=it3->begin();it2!=it3->end()-1;it2++)
			{
				cout<<*it2<<",";
				//printf("%d,",*it2);
			}
			cout<<*it2<<endl;
			//printf("%d\n",*it2);
			}
	}
		b++;
	}
}
//////////////////////////////////////////////////////////////////////////////
int main()
{
	clock_t t=clock();
	DrawGraph();
	freopen("E:\\vscode\\huawei\\johnson\\answer.txt","w",stdout);
	Johson_Search();
	RESULT();
	freopen("CON", "w", stdout);
	freopen("CON", "r", stdin);
	clock_t t1=clock();
	cout<<(t1-t)*1000/CLOCKS_PER_SEC<<"ms"<<endl;
	system("pause");
	return 0;

}